function iset (...args) {
  return new ISet(...args)
}

function isArr (v) {
  return Object.prototype.toString.call(v) === '[object Array]'
}

function isSet (v) {
  return Object.prototype.toString.call(v) === '[object Set]'
}

export class ISet extends Set {
  toArray () {
    return [...this]
  }

  // 并集
  union () {
    const nset = new Set(this)
    for (let i = 0; i < arguments.length; i++) {
      if (!isSet(arguments[i]) && !isArr(arguments[i])) throw new Error('Params must be Set or Array')
      for (const val of arguments[i]) {
        nset.add(val)
      }
    }

    return [...nset]
  }

  // 交集
  intersection (b) {
    const arr = [...b].filter(e => this.has(e))
    return arr.filter((e, index) => arr.indexOf(e) === index) // 去重
  }

  // 差集
  difference (b) {
    const bset = new Set(b)
    return [...this].filter(e => !bset.has(e))
  }

  // 是否是b的子集
  isSubset (b) {
    const bset = new Set(b)
    for (const v of this) {
      if (!bset.has(v)) return false
    }
    return true
  }

  // 是否包含b
  isSuperset (b) {
    const bset = new Set(b)
    if (bset.size > this.size) return false

    for (const v of bset) {
      if (!this.has(v)) return false
    }
    return true
  }
}

export default iset
